1. Memahami Konsep Rekursi
👩🏫 Secara Formal:
Rekursi (Recursion) adalah sebuah teknik pemrograman di mana sebuah fungsi (atau *procedure*) memanggil dirinya sendiri untuk menyelesaikan sub-masalah yang lebih kecil. Agar tidak terjadi perulangan tak hingga (*infinite loop*), sebuah fungsi rekursif wajib memiliki Base Case (kondisi berhenti) dan Recurrence Relation (langkah rekursif yang menuju ke base case).
Bayangin kamu dikasih kado Boneka Matryoshka (boneka Rusia yang berlapis-lapis). Kamu disuruh mencari sebuah cincin kecil di dalamnya.
- Langkahmu: Buka boneka. Kalau di dalamnya ada cincin, Selesai! (Ini namanya Base Case).
- Kalau di dalamnya ada boneka yang lebih kecil, kamu ulangi langkah yang sama: Buka boneka itu lagi! (Ini namanya Recursive Step).
Fungsi rekursif juga begitu, dia akan terus "membuka" tugas yang makin kecil sampai dia ketemu jawaban pastinya, lalu bawa jawabannya naik lagi ke atas!
Kondisi paling sederhana yang nilainya sudah diketahui langsung tanpa harus memanggil fungsi rekursif lagi. Berfungsi untuk menghentikan rekursi.
Aturan yang mengubah masalah besar menjadi masalah yang lebih kecil, dan diteruskan dengan memanggil fungsi itu sendiri lagi.
⚠️ Common Mistakes di OSN
- Missing Base Case: Lupa memberikan kondisi berhenti, mengakibatkan
Stack Overflow(program crash karena memori penuh). - Salah Menempatkan Base Case: Menaruh base case di bawah recursive call. Base case harus selalu ditaruh di awal fungsi sebelum rekursi memanggil kembali.
- Lupa
return: Pada fungsi yang mengembalikan nilai, lupa menulisreturnsaat memanggil fungsi rekursif, sehingga hasil perhitungan dari fungsi anak tidak tersampaikan ke fungsi pemanggilnya.
Animasi: Call Stack & Rekursi
Ketika fungsi memanggil dirinya sendiri, komputer menggunakan memori bernama Stack untuk menumpuk tugas (*Call Stack*). Perhatikan animasi hitungMundur(3) di bawah ini!
voidhitungMundur(intn) {if(n == 0) { cout <<"Selesai!";return; // Base case } cout << n <<" "; hitungMundur(n - 1); // Rekursi }
Lab: Simulator Tracing Faktorial
Berbeda dengan prosedur hitungMundur yang tidak mengembalikan nilai (void), fungsi matematika seperti Faktorial (N!) mengembalikan nilai (return) yang harus ditangkap oleh si pemanggil di dalam stack saat dia turun / selesai. Coba jalankan step-by-step!
int faktorial(int N) { if (N == 1) return 1; else return N * faktorial(N - 1); } int main() { int hasil = faktorial(3); }
Question Card
Apa yang akan terjadi pada memori komputer jika kita lupa membuat Base Case pada fungsi rekursif?
Akan terjadi Stack Overflow (Tumpukan Meluap)! Karena fungsi tidak tahu kapan harus berhenti, ia akan terus menumpuk Call Stack di memori sampai memori komputermu penuh, lalu program akan crash atau error. (Sama seperti masukin kado Matryoshka tanpa henti).
⚠️ Common Mistakes: Pass by Value vs Reference
Saat melakukan rekursi mendalam (seperti Backtracking atau DFS) dengan tipe data berat (seperti vector atau string di C++), hindari mem-passing parameter secara Value.
Solusi: Gunakan Pass-by-Reference (vector<int>& arr) agar array tidak di-copy berulang kali di memori setiap kali fungsi dipanggil, yang dapat memicu Time Limit Exceeded (TLE) atau Memory Limit Exceeded (MLE).